home *** CD-ROM | disk | FTP | other *** search
- /* Functions for creating, deleting, and renaming files.
-
- 93/10/20 aih
- - FileUnique now checks for folder name conflicts as well, and made
- file name construction a little more intelligent so that it can be
- used with user-visible files.
-
- 93/10/14 aih
- - an existing file is no longer deleted before creating a new file
-
- 93/03/26 AIH
- - Added function to get a unique file name in a list of directories
-
- 91/05/15 AIH
- - Added some comments
- - Made maximum file length for unique files 14 chars
-
- 91/05/06 Ari Halberstadt (AIH)
- - Fixed bug in FileUnique. */
-
- #include <limits.h>
- #include <stdarg.h>
- #include <stdio.h>
- #include <string.h>
- #include "pstr.h"
- #include "MathLib.h"
- #include "StringLib.h"
- #include "FileLib.h"
- #include "FolderLib.h"
-
- /* delete the file */
- void FileDelete(FileType *fp)
- {
- require(FileValid(fp));
- FailOSErr(HDelete(fp->vol, fp->dir, fp->pnm));
- }
-
- /* erase the either the data or the resource fork of the file, whichever
- is open */
- static void FileEraseFork(FileType *fp)
- {
- char buffer[FILE_BUFSIZ];
- FilePosType size;
- FilePosType count;
-
- require(FileValid(fp));
- require(fp->ref != FILE_CLOSED);
- memclr(buffer, FILE_BUFSIZ);
- size = FileSize(fp);
- while (size > 0) {
- count = min(size, FILE_BUFSIZ);
- size -= count;
- FileWrite(fp, count, buffer);
- }
- }
-
- /* erase the data fork */
- static void FileEraseData(FileType *fp)
- {
- TRY {
- FileOpen(fp, fsWrPerm);
- FileEraseFork(fp);
- } CLEANUP {
- FileClose(fp);
- } ENDTRY;
- }
-
- /* erase the resource fork */
- static void FileEraseRes(FileType *fp)
- {
- TRY {
- FileOpenRes(fp, fsWrPerm);
- FileEraseFork(fp);
- } CLEANUP {
- FileClose(fp);
- } ENDTRY;
- }
-
- /* Erase both forks of the file by writing over them with zeroes.
- This is more secure than just deleting a file since the operating
- system just removes the reference to the file, not the actual data.
- You may want to call this function more than once to ensure that
- all the data are completely erased (various devices are capable of
- reading the faint signals that remain on erased disks). You should
- also beware of files which may have shrunk, or which have changed
- the sectors they are on, since the unused sectors may still contain
- valuable data which are not erased by this function. */
- void FileErase(FileType *fp)
- {
- FileEraseData(fp);
- FileEraseRes(fp);
- }
-
- /* create the file using the specified creator and type */
- void FileCreate(FileType *fp, OSType creator, OSType type)
- {
- FailOSErr(HCreate(fp->vol, fp->dir, fp->pnm, creator, type));
- }
-
- /* Rename the file. The file parameter (fp) is updated accordingly. */
- void FileRename(FileType *fp, const FileNameType name)
- {
- FilePNameType newname;
-
- require(FileValid(fp));
- require(StrValid(name, sizeof(FileNameType)));
- FailOSErr(HRename(fp->vol, fp->dir, fp->pnm, c2pstrcpy(newname, name)));
- FileNameSet(fp, name);
- }
-
- /* This is the almost the same as FileUnique, but it will generate a file
- name which is unique in all of the specified directories. The name
- field of the directory specifications is ignored. The last directory
- should be NULL. The parameters following 'orignm' should be of
- type FileType, and contain the the directory specifications. */
- void FileUniqueInList(FileNameType orignm, ...)
- {
- const short maxtry = TMP_MAX;
- const short maxlen = sizeof(FileNameType); /* program_note: use 14 chars if need compatability with A/UX 1.0 */
- FileType file, *cfp = &file; /* file being checked */
- FileType *dirfp; /* directory to check */
- FileNameType name; /* file's name */
- CStr31 num; /* number we're trying */
- short try; /* current number we're trying */
- short len; /* length of name */
- short i; /* index to directories */
- va_list ap; /* for accessing the list of directories */
- Boolean found; /* true if found a unique name */
-
- /* give a new numeric suffix to the file until either a unique
- name is generated or the maximum number of attempts is exceeded */
- check(0 < maxlen && maxlen <= sizeof(FileNameType));
- check(0 < maxtry);
- try = 0;
- found = false;
- strcpy(name, orignm);
- do {
-
- /* check if a file with the name exists in any of the directories */
- va_start(ap, orignm);
- do {
- dirfp = va_arg(ap, FileType *);
- if (dirfp) {
- FileClone(dirfp, cfp);
- FileNameSet(cfp, name);
- }
- } while (dirfp && ! FileExists(cfp) && ! FolderExists(cfp));
- va_end(ap);
- found = (! dirfp);
-
- /* append numeric suffix, being careful with length of name */
- if (! found) {
- NumToString(try + 2, (StringPtr) num);
- p2cstr((StringPtr) num);
- check(maxlen > strlen(num) + 2);
- len = maxlen - strlen(num) - 2;
- strncpy(name, orignm, len);
- name[len] = 0;
- strcat(name, " ");
- strcat(name, num);
- }
-
- } while (! found && ++try < maxtry);
-
- if (! found) {
- /* gave up */
- check(try == maxtry);
- FailOSErr(dupFNErr);
- }
-
- strcpy(orignm, name);
- }
-
- /* Generate a unique name for the file (useful for temporary files).
- The unique file's name is of the form <Name><Number>, where <Name>
- is the file's original name and <Number> is some unique integer.
- The resulting file name is truncated to 14 characters to ensure
- that it will be unique even on volumes created by A/UX 1.0 (see
- TN229). If no unique file name could be generated then
- dupFNErr is raised. */
- void FileUnique(FileType *fp)
- {
- FileNameType name;
-
- strcpy(name, FileName(fp));
- FileUniqueInList(name, fp, NULL);
- FileNameSet(fp, name);
- ensure(! FileExists(fp) && ! FolderExists(fp));
- }
-